<?php
/* 
 * ********* CVS HEADER ********* 
 * 
 * $RCSfile: article.php,v $ 
 * $Date: 2005/08/31 10:13:46 $ 
 * $Revision: 1.3 $ 
 * 
 * ********* CVS HEADER ********* 
 */
// retourne le texte avec les intertitres remplaces
// syntaxe : {{{le titre}}}
function remplace_intertitre($texte){
	$texte = str_replace("{{{", "<h3 class=\"article\">", $texte);
	$texte = str_replace("}}}", "</h3>", $texte);
	return $texte;
}

// retourne le texte avec les paragraphes remplaces
// syntaxe : Passer une ligne
function remplace_paragraphe($texte){
	$texte = ereg_replace("(( *)\n){2,}", "\n<p>", $texte);
	$texte = str_replace("<p>", "<p class=\"article\">", $texte);
	if (strpos(' '.$texte, '<p class="article">'))
		$texte = '<p class="article">'.str_replace('<p class="article">', "</p>\n".'<p class="article">', $texte).'</p>';
	return $texte;	
}

// retourne le texte avec le gras remplace
// syntaxe : {{texte en gras}}
function remplace_gras($texte){
	$texte = str_replace("{{", "<b class=\"article\">", $texte);
	$texte = str_replace("}}", "</b>", $texte);
	return $texte;	
}

// retourne le texte avec l'italique remplace
// syntaxe : {texte en italic}
function remplace_italique($texte){
	$texte = str_replace("{", "<i class=\"article\">", $texte);
	$texte = str_replace("}", "</i>", $texte);
	return $texte;
}

function traiter_listes ($texte) {
	$parags = split ("\n[[:space:]]*\n", $texte);
	//$parags = split ("\n *\n", $texte);
	unset($texte);
	// chaque paragraphe est traite a part
	while (list(,$para) = each($parags)) {
		$niveau = 0;
		$lignes = explode("\n-", "\n" . $para);
		// ne pas toucher a la premiere ligne
		list(,$debut) = each($lignes);
		$texte .= $debut;

		// chaque item a sa profondeur = nb d'etoiles
		unset ($type);
		while (list(,$item) = each($lignes)) {
			ereg("^([*]*|[#]*)([^*#].*)", $item, $regs);
			$profond = strlen($regs[1]);

			if ($profond > 0) {
				unset ($ajout);

				// changement de type de liste au meme niveau : il faut
				// descendre un niveau plus bas, fermer ce niveau, et
				// remonter
				$nouv_type = (substr($item,0,1) == '*') ? 'ul' : 'ol';
				$change_type = ($type and ($type <> $nouv_type) and ($profond == $niveau)) ? 1 : 0;
				$type = $nouv_type;

				// d'abord traiter les descentes
				while ($niveau > $profond - $change_type) {
					$ajout .= $pile_li[$niveau];
					$ajout .= $pile_type[$niveau];
					if (!$change_type)
						unset ($pile_li[$niveau]);
					$niveau --;
				}

				// puis les identites (y compris en fin de descente)
				if ($niveau == $profond && !$change_type) {
					$ajout .= $pile_li[$niveau];
				}

				// puis les montees (y compris apres une descente un cran trop bas)
				while ($niveau < $profond) {
					$niveau ++;
					$ajout .= "<$type class=\"article\">";
					$pile_type[$niveau] = "</$type>";
				}

				$ajout .= "<li class=\"article\">";
				$pile_li[$profond] = "</li>";
			} else {
				$ajout = "\n-";	// puce normale ou <hr>
			}

			$texte .= $ajout . $regs[2];
		}

		// retour sur terre
		unset ($ajout);
		while ($niveau > 0) {
			$ajout .= $pile_li[$niveau];
			$ajout .= $pile_type[$niveau];
			$niveau --;
		}
		$texte .= $ajout;

		// paragraphe
		$texte .= "\n\n";
	}

	// sucrer les deux derniers \n
	return substr($texte, 0, -2);
}

// retourne les listes a puce remplacees
// syntaxe : -*premier element
//           -*deuxieme element
//           - ...
function remplace_liste($texte){
	if (ereg("\n-[*#]", "\n".$texte))
	return traiter_listes($texte);
	return $texte;
}

// retourne les traits de separation remplaces
// syntaxe : ... (ou plus de points)
function remplace_trait_separation($texte){
	$texte = ereg_replace("(^|\n)(-{4,}|_{4,})", "<hr />", $texte);
	return $texte;
}

// retourne les liens vers des articles
// syntaxe : [texte->num_article]
function extraire_lien_article($texte){
	$regexp = "([[:digit:]]+)$";
	if(ereg($regexp, $texte, $regs)){
		echo "IMG ".$regs[1];	
	}
	return $texte;
}

function extraire_lien ($regs) {
	$lien_texte = $regs[1];

	$lien_url = trim($regs[3]);
	// page html dans RPortal identifie par son ID
	if(ereg("^([[:digit:]]+)$",$lien_url, $a)){
		$query="SELECT titre,code FROM html WHERE id='$lien_url'";
		$result=rportalrequete($query) or rportalerreur("$query","?op=");
		if(rportalnbresult($result)==1){
			$p = rportalligne($result);
			$lien_url = "?op=html&code=".$p['code'];
			if (!$lien_texte) {
				$lien_texte = ereg_replace('"', '', $p['titre']);
				if (strlen($lien_texte)>40)
					$lien_texte = substr($lien_texte,0,35).'...';
				$class_lien = "url";
			}			
		}else{
			$lien_url = "?op=";
		}
	}else{
		$class_lien = "out";
		// petites corrections d'URL
		// page html dans RPortal identifie par son code
		$query= "SELECT titre,code FROM html WHERE code='$lien_url'";
		$result=rportalrequete($query) or rportalerreur("$query","?op=");
		if(rportalnbresult($result)==1){
			$p = rportalligne($result);
			$lien_url = "?op=html&code=".$p['code'];
			if (!$lien_texte) {
				$lien_texte = ereg_replace('"', '', $p['titre']);
				if (strlen($lien_texte)>40)
					$lien_texte = substr($lien_texte,0,35).'...';
				$class_lien = "url";
			}			
		}else if (ereg("^www\.[^@]+$",$lien_url)){
			$lien_url = "http://".$lien_url;
		}
		//else if (strpos($lien_url, "@") && email_valide($lien_url))
		//	$lien_url = "mailto:".$lien_url;
	}
	// texte vide ?
	if (!$lien_texte) {
		$lien_texte = ereg_replace('"', '', $lien_url);
		if (strlen($lien_texte)>40)
			$lien_texte = substr($lien_texte,0,35).'...';
		$class_lien = "url";
	}
	$insert = "<a href=\"$lien_url\" class=\"article_$class_lien\""
		.">".$lien_texte."</a>";

	return array($insert, $lien_url);
}

// retourne les liens remplaces
// syntaxe : [texte->URL]
function remplace_lien($texte){
	$regexp = "\[([^][]*)->(>?)([^]]*)\]";
	$texte_a_voir = $texte;
	$texte_vu = '';
	while (ereg($regexp, $texte_a_voir, $regs)) {
		list($insert, $lien) = extraire_lien($regs);
		$pos = strpos($texte_a_voir, $regs[0]);
		$texte_vu .= substr($texte_a_voir, 0, $pos) . $insert;
		$texte_a_voir = substr($texte_a_voir, $pos + strlen($regs[0]));
	}
	$texte = $texte_vu.$texte_a_voir; 
	return $texte;
}



// permet de faire des references "note en bas de page"
// syntaxe : [[texte de la note]]  (sera remplacee par un numero auto)
//           [[<x>texte de la note]] (sera remplace par le numero x)
function remplace_note_bas_de_page($texte){
	global $rportalparams;
	$ouvre_ref = $rportalparams->get_value("RPORTAL","contenu.article.ouvre_ref");
	$ferme_ref = $rportalparams->get_value("RPORTAL","contenu.article.ferme_ref");
	$ouvre_note= $rportalparams->get_value("RPORTAL","contenu.article.ouvre_note");
	$ferme_note= $rportalparams->get_value("RPORTAL","contenu.article.ferme_note");
	
	$compt_note = 0;
	$texte_a_voir = $texte;
	$texte_vu = '';
	$regexp = "\[\[(([^]]|[^]]\][^]])*)\]\]";
	/* signifie : deux crochets ouvrants, puis pas-crochet-fermant ou
		crochet-fermant entoure de pas-crochets-fermants (c'est-a-dire
		tout sauf deux crochets fermants), puis deux fermants */
	while (ereg($regexp, $texte_a_voir, $regs)) {
		$note_source = $regs[0];
		$note_texte = $regs[1];
		$num_note = false;

		// note auto ou pas ?
		if (ereg("^ *<([^>]*)>", $note_texte, $regs)){
			$num_note = $regs[1];
			$note_texte = ereg_replace ("^ *<([^>]*)>", "", $note_texte);
		} else {
			$compt_note++;
			$num_note = $compt_note;
		}

		// preparer la note
		if ($num_note) {
			if ($marqueur_notes) // ??????
				$mn = $marqueur_notes.'-';
			$ancre = $mn.urlencode($num_note);
			$insert = "$ouvre_ref<a href=\"#nb$ancre\" name=\"nh$ancre\" class=\"article_note\">$num_note</a>$ferme_ref";
			$appel = "$ouvre_note<a href=\"#nh$ancre\" name=\"nb$ancre\" class=\"article_note\">$num_note</a>$ferme_note";
		} else {
			$insert = '';
			$appel = '';
		}

		// l'ajouter "brut" dans les notes
		if ($note_texte) {
			if ($mes_notes)
				$mes_notes .= "\n\n";
			$mes_notes .= $appel . $note_texte;
		}
	
		// dans le texte, mettre l'appel de note a la place de la note
		$pos = strpos($texte_a_voir, $note_source);
		$texte_vu .= substr($texte_a_voir, 0, $pos) . $insert;
		$texte_a_voir = substr($texte_a_voir, $pos + strlen($note_source));
	}
	$note_epurer = epurer($mes_notes);
	$mes_notes = '';
	if(trim($note_epurer)!=''){
		$mes_notes = '<div class="article_note">'.$note_epurer.'</div>';
	}
	$texte = $texte_vu . $texte_a_voir.$mes_notes;
	return $texte;
}

// remplace les images telechargees pour l'article
// syntaxe : <IMGx|left>   ou x est le numero de l'image telechargee
//           <IMGx|center>
//           <IMGx|right>
function remplace_image($texte){
	while (eregi("<(IMG)([0-9]+)(\|([^\>]*))?".">", $texte, $match)) {
		$num_echap++;

		$letout = quotemeta($match[0]);
		$letout = ereg_replace("\|", "\|", $letout);
		$id_document = $match[2];
		$align = $match[4];
		//echo "IMG: ".$id_document." , ".$align." , ".$match[1]."<br/>";
		$f = '';
		if(file_exists('images/article/'.$id_document.'.jpeg'))
			$f = 'images/article/'.$id_document.'.jpeg';
		else if(file_exists('images/article/'.$id_document.'.jpg'))
			$f = 'images/article/'.$id_document.'.jpg';
		else if(file_exists('images/article/'.$id_document.'.gif'))
			$f = 'images/article/'.$id_document.'.gif';
		else if(file_exists('images/article/'.$id_document.'.bmp'))
			$f = 'images/article/'.$id_document.'.bmp';
		else if(file_exists('images/article/'.$id_document.'.png'))
			$f = 'images/article/'.$id_document.'.png';
		$texte = ereg_replace($letout, "<img src='$f' align='$align' border='0' />", $texte);
	}
	return $texte;
}

// remplace les tableaux
// syntaxe : |aaa|bbb|ccc|
//           |xxx|yyy|zzz|
function remplace_tableau($texte){
	$texte = ereg_replace("^\n?\|", "\n\n|", $texte);
	$texte = ereg_replace("\|\n?$", "|\n\n", $texte);

	$tableBeginPos = strpos($texte, "\n\n|");
	$tableEndPos = strpos($texte, "|\n\n");
	while (is_integer($tableBeginPos) && is_integer($tableEndPos) && $tableBeginPos < $tableEndPos + 3) {
		$textBegin = substr($texte, 0, $tableBeginPos);
		$textTable = substr($texte, $tableBeginPos + 2, $tableEndPos - $tableBeginPos);
		$textEnd = substr($texte, $tableEndPos + 3);

		$newTextTable = "\n<p><table class=\"article\">";
		$rowId = 0;
		$lineEnd = strpos($textTable, "|\n");
		while (is_integer($lineEnd)) {
			$rowId++;
			$row = substr($textTable, 0, $lineEnd);
			$textTable = substr($textTable, $lineEnd + 2);
			if ($rowId == 1 && ereg("^(\\|[[:space:]]*\\{\\{[^}]+\\}\\}[[:space:]]*)+$", $row)) {
				$newTextTable .= '<tr class="row_first">';
			} else {
				$newTextTable .= '<tr class="liste_'.($rowId % 2 ? 'paire' : 'impaire').'">';
			}
			$newTextTable .= ereg_replace("\|([^\|]+)", "<td>\\1</td>", $row);
			$newTextTable .= '</tr>';
			$lineEnd = strpos($textTable, "|\n");
		}
		$newTextTable .= "</table>\n<p>\n";

		$texte = $textBegin . $newTextTable . $textEnd;

		$tableBeginPos = strpos($texte, "\n\n|");
		$tableEndPos = strpos($texte, "|\n\n");
	}
	return trim($texte);
}

function remplace_retour_chariot($texte){
	$texte = ereg_replace ("\r\n?", "\n",$texte);
	return $texte;
}

// Securite : empecher l'execution de code PHP
function interdire_scripts($source) {
	$source = eregi_replace("<(\%|\?|([[:space:]]*)script)", "&lt;\\1", $source);
	return $source;
}

// Echappement des entites HTML avec correction des entites "brutes"
// (generees par les butineurs lorsqu'on rentre des caracteres n'appartenant
// pas au charset de la page [iso-8859-1 par defaut])
function corriger_entites_html($texte) {
	return ereg_replace('&amp;(#[0-9]+;)', '&\1', $texte);
}

// idem mais corriger aussi les &amp;eacute; en &eacute; (etait pour backends, mais n'est plus utilisee)
function corriger_toutes_entites_html($texte) {
	return eregi_replace('&amp;(#?[a-z0-9]+;)', '&\1', $texte);
}

function remplace_entites_html($texte) {
	return corriger_entites_html($texte);
}

// Remplace les '&' par le code html correspondant '&amp;' 
function remplace_amp($texte) {
	return ereg_replace('&(#[0-9]+;)', '&amp;\\1', $texte);
}

//function traite_article($texte){
//	return 	epurer($texte,true);
//}

//require_once(get_path_module("contenu.wikirenderer"));
//require_once(get_path_module("contenu.wikirenderer.rportal"));
function traite_article($texte){
	$texte = preg_replace("'<script[^>]*>.*</script[^>]*>'siU",'',$texte);
	$texte = preg_replace("'<\?.*\?>'siU",'',$texte);
	return $texte;
//	$cfg = new WikiRPortalConfig();
//	$ctr=new WikiRenderer($cfg);
//	return 	$ctr->render($texte);
}

function epurer($texte,$note=false){
	global $rportalparams;
	$puce = $rportalparams->get_value("RPORTAL","contenu.article.puce");
	$texte = remplace_entites_html($texte);

	$texte = remplace_retour_chariot($texte);


	if($note==true)
	$texte = remplace_note_bas_de_page($texte);
	$texte = remplace_lien($texte);
	$texte = remplace_image($texte);
	$texte = remplace_tableau($texte);
	$texte = remplace_liste($texte);
	
	$texte = remplace_trait_separation($texte);
	$texte = remplace_intertitre($texte);
	$texte = remplace_gras($texte);
	$texte = remplace_italique($texte);
	
	$texte = ereg_replace("^- *", "$puce&nbsp;", $texte);
	$texte = ereg_replace("\n-- *", "\n<br />&mdash;&nbsp;",$texte);
	$texte = ereg_replace("\n- *", "\n<br />$puce&nbsp;",$texte);
	$texte = ereg_replace("\n_ +", "\n<br />",$texte);
	
	$texte = remplace_paragraphe($texte);
	
	$texte = str_replace("\n", " ", $texte);
	$texte = interdire_scripts($texte);
	
	return $texte;	
}
?>